#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>  
// 信号处理函数，当接收到指定信号时会被调用
void intsig_handler (int signumber, siginfo_t *siginfo, void *empty)
{
    // 打印当前进程的 PID 以及处理信号的提示信息
    printf("int_handler, my pid=%d\n", getpid());
}

int main()
{
    int pid;
    // 定义一个 sigaction 结构体变量，用于设置信号处理动作
    struct sigaction act;   
    // 定义一个字符串指针数组，作为要执行的命令的参数，这里是 "ls -l" 中的 "-l"
    // 注意：数组最后应添加 NULL 以符合 execvp 函数要求，原代码此处缺少
    char *arg[] = {"-l", NULL};

    // 将信号处理函数 intsig_handler 赋值给 sigaction 结构体的 sa_sigaction 成员
    act.sa_sigaction = intsig_handler; 
    // 设置信号处理标志，SA_SIGINFO 表示使用 sa_sigaction 而不是 sa_handler 来处理信号
    act.sa_flags = SA_SIGINFO; 

    // 使用 sigaction 函数设置 SIGINT 信号的处理动作
    if (sigaction(SIGINT, &act, NULL) < 0)
    {
        // 如果设置失败，打印错误信息
        printf("install sigal error\n");
    }

    // 打印父进程的 PID
    printf("The parent pid =%d\n", getpid());

    // 创建一个子进程，返回值 pid 用于区分父进程和子进程
    pid = fork();

    // 如果 fork 调用失败，pid 会小于 0
    if (pid < 0)
    {
        // 打印 fork 失败的错误信息
        perror("fork failed!\n");
        // 终止程序
        exit(0);
    }

    // 打印 fork 函数的返回值，在父进程中是子进程的 PID，在子进程中是 0
    printf("The return fork =%d\n", pid);

    // 如果是子进程（pid 为 0）
    if (pid == 0)
    {
        // 子进程调用 execvp 函数执行 "ls -l" 命令
        execvp("ls", arg);
    }
    else
    {
        // 父进程进入一个无限循环，等待信号
        while(1);
    }
}